<?php

class Application_Plugin_Acl extends Zend_Controller_Plugin_Abstract 
{
    protected $_acl;
    protected $_modelAcl;

    public function __construct() {  
        if (!$this->_acl = My_Cache::getCache('acl')) {            
            $this->_acl      = new Zend_Acl();        
            $this->_modelAcl = new Application_Model_Acl();
            
            //adding all existing resources(controllers)
            $controllers = $this->_modelAcl->getAllControllers();
            foreach ($controllers as $controller) {
                $this->_acl->add(new Zend_Acl_Resource($controller['resource']));
            }

            $roles = $this->_modelAcl->getAllRoles();
            foreach ($roles as $role) {
                //adding all existing roles
                $this->_acl->addRole(new Zend_Acl_Role($role['role']));
                //admin have full access by default
                if ($role['role'] == 'admin') {
                    $this->_acl->allow($role['role'], null);
                    continue;
                }
                //deny all resources by default
                $this->_acl->deny($role['role'], null);
                
                //getting all role resources
                $roleControllers = $this->_modelAcl->getRoleResources($role['id']);                                
                
                foreach ($roleControllers as $roleController) {
                    $actions = array();                    
                    $roleActions = $this->_modelAcl->getRoleResources($role['id'], $roleController['id']);                    
                    foreach ($roleActions as $roleAction) {
                        $actions[] = $roleAction['resource'];
                    }    

                    $this->_acl->allow($role['role'], $roleController['resource'], $actions);                
                }            
            }    
            My_Cache::saveCache($this->_acl, 'acl');
        }          

        /*$timeEnd = microtime(true);        
        $executionTime = ($timeEnd - $timeStart)/60;        
        echo '<b>Total Execution Time:</b> '.$executionTime.' Mins';*/
        
        Zend_Registry::set('acl', $this->_acl);      
    }
    
    public function preDispatch(Zend_Controller_Request_Abstract $request) {
        $auth = Zend_Auth::getInstance();        
        $acl  = Zend_Registry::get('acl');                 
        if ($auth->hasIdentity()) {
            $identity = $auth->getIdentity();            
            if (property_exists($identity, 'role')) {
                $role = $auth->getIdentity()->role;
            } else {
                $role = 'guest';
            }
        } else {
            $role = 'guest';
        }

        if (!$acl->hasRole($role))
            $role = 'guest';
        
        $module    = empty($request->module)?'default':$request->module;
        $resource  = $module. ':'. $request->controller;
        $privilege = $request->action;       

        if (!$acl->has($resource))
            $resource = null;        

        if (!$acl->isAllowed($role, $resource, $privilege)) {             
            $request->setModuleName('');
            $request->setControllerName('index');
            $request->setActionName('index');
        }
    }      
}

?>
